﻿using System;
using System.Windows.Forms;
using Nortec.Security;
using Nortec.Security.BusinessComponents;
using Nortec.Security.BusinessEntities;
using Infragistics.Win.UltraWinGrid;
using Infragistics.Win;
using System.Collections;

namespace Litografia.UI.Seguridad
{
    public partial class RolesForm : BaseForm
    {
        public RolesForm()
        {
            InitializeComponent();
        }

        #region Declarations
        BERol.RolDataTable appRoles;
        BERol.RolRow selectedRole;
        #endregion

        #region Event Handlers
        private void RolesForm_Load(object sender, EventArgs e)
        {
            ConfigureToolBar(toolStrip, ToolBarButtons.Save |
                                        ToolBarButtons.New |
                                        ToolBarButtons.Delete |
                                        ToolBarButtons.Close);
            LoadPrivilegiosTree();
            LoadPrivilegiosList();
            LoadRolesGrid(true);
            ConfigureRolesGrid();
            toolStrip.ItemClicked += toolStrip_ItemClicked;
            ToggleButton(toolStrip, ToolBarButtons.Delete, false);
        }
        private void toolStrip_ItemClicked(object sender, ToolStripItemClickedEventArgs e)
        {
            switch ((ToolBarButtons)e.ClickedItem.Tag)
            {
                case ToolBarButtons.Save:
                    Save();
                    break;
                case ToolBarButtons.Delete:
                    Delete();
                    break;
                case ToolBarButtons.New:
                    ClearControls(Controls);
                    txtNombre.Focus();
                    ToggleButton(toolStrip, ToolBarButtons.Delete, false);
                    rolesGrid.Selected.Rows.Clear();
                    rolesGrid.Refresh();
                    break;
                case ToolBarButtons.Close:
                    Close();
                    break;
            }
        }
        private void rolesGrid_AfterSelectChange(object sender, AfterSelectChangeEventArgs e)
        {
            if (rolesGrid.Selected.Rows.Count > 0)
            {
                var selectedId = (int)rolesGrid.Selected.Rows[0].Cells[appRoles.lit_rol_idColumn.Ordinal].Value;
                selectedRole = appRoles.FindBylit_rol_id(selectedId);
                UnPackRole(selectedRole);
                ToggleButton(toolStrip, ToolBarButtons.Delete, true);
            }
            else
            {
                selectedRole = null;
                ToggleButton(toolStrip, ToolBarButtons.Delete, false);
            }
        }
        #endregion

        #region Methods: Private
        private void LoadRolesGrid(bool sort)
        {
            BCSecurity securityObject = new BCSecurity();
            appRoles = securityObject.GetAllRoles(NortecMembership.ApplicationId);
            rolesGrid.DataSource = appRoles;
            rolesGrid.Selected.Rows.Clear();

            if (sort)
            {
                rolesGrid.DisplayLayout.Bands[0].SortedColumns.Clear();
                rolesGrid.DisplayLayout.Bands[0].SortedColumns.Add(rolesGrid.DisplayLayout.Bands[0].Columns[appRoles.lit_rol_nombreColumn.Ordinal], false);
            }

            if (rolesGrid.Rows.Count > 0)
            {
                rolesGrid.ActiveRow = rolesGrid.Rows[0];
               // rolesGrid.Selected.Rows.Add(rolesGrid.Rows[0]);
            }
            else
            {
                selectedRole = null;
                ToggleButton(toolStrip, ToolBarButtons.Delete, false);
            }
        }
        private void LoadPrivilegiosTree()
        {
            BCSecurity securityObject = new BCSecurity();
            BEPrivilegio.PrivilegioDataTable privilegios = securityObject.GetRights(NortecMembership.ApplicationId, "menu");
            TreeNode rootNode = new TreeNode("Todos");
            rootNode.Tag = null;

            LoadTreeNode(rootNode, 0, privilegios);
            rightsTree.Nodes.Add(rootNode);
            rightsTree.ExpandAll();
        }
        private void LoadPrivilegiosList()
        {
            BCSecurity securityObject = new BCSecurity();
            BEPrivilegio.PrivilegioDataTable privilegios = securityObject.GetRights(NortecMembership.ApplicationId, "permiso");
            rightsList.DataSource = privilegios;
            rightsList.DisplayMember = privilegios.lit_privilegio_descColumn.ColumnName;
            rightsList.ValueMember = privilegios.lit_privilegio_idColumn.ColumnName;
        }
        private void LoadTreeNode(TreeNode parentNode, int parentRightId, BEPrivilegio.PrivilegioDataTable appRights)
        {
            foreach (BEPrivilegio.PrivilegioRow right in appRights.Select("lit_privilegio_padre_id " + ((parentRightId > 0)? "= " + parentRightId : " IS NULL")))
            {
                TreeNode node = new TreeNode(right.lit_privilegio_desc);
                node.Tag = right;
                LoadTreeNode(node, right.lit_privilegio_id, appRights);
                parentNode.Nodes.Add(node);
            }
        }
        private void ConfigureRolesGrid()
        {

            // Oculta algunas columnas 
            rolesGrid.DisplayLayout.Bands[0].Columns[appRoles.lit_rol_idColumn.Ordinal].Hidden = true;
            rolesGrid.DisplayLayout.Bands[0].Columns[appRoles.lit_aplicacion_idColumn.Ordinal].Hidden = true;
            
            // Alineamientos
            foreach (UltraGridColumn col in rolesGrid.DisplayLayout.Bands[0].Columns)
                col.Header.Appearance.TextHAlign = HAlign.Center;
            
            // Ancho de columnas
            rolesGrid.DisplayLayout.Bands[0].Columns[appRoles.lit_rol_nombreColumn.Ordinal].Width = 98;
            rolesGrid.DisplayLayout.Bands[0].Columns[appRoles.lit_rol_descColumn.Ordinal].Width = 200;
            
            // Filters
            rolesGrid.DisplayLayout.Bands[0].Columns[appRoles.lit_rol_nombreColumn.Ordinal].AllowRowFiltering = DefaultableBoolean.False;
            rolesGrid.DisplayLayout.Bands[0].Columns[appRoles.lit_rol_descColumn.Ordinal].AllowRowFiltering = DefaultableBoolean.False;
            rolesGrid.DisplayLayout.Bands[0].Columns[appRoles.lit_rol_nombreColumn.Ordinal].Header.Caption = "Nombre";
            rolesGrid.DisplayLayout.Bands[0].Columns[appRoles.lit_rol_descColumn.Ordinal].Header.Caption = "Descripción";

            rolesGrid.DisplayLayout.Bands[0].Override.CellClickAction = CellClickAction.RowSelect;
        }
        private void UnPackRole(BERol.RolRow role)
        {
            BCSecurity securityObject = new BCSecurity();

            txtNombre.Text = role.lit_rol_nombre;
            txtDesc.Text = role.lit_rol_desc;
           
            BEPrivilegio.PrivilegioDataTable roleRights = securityObject.GetRightsForRole(role.lit_rol_nombre, NortecMembership.ApplicationId);
            CheckTreeNodes(rightsTree.TopNode, roleRights);
            CheckRightsInList(roleRights);
        }
        private void CheckTreeNodes(TreeNode parentNode, BEPrivilegio.PrivilegioDataTable roleRights)
        {
            foreach (TreeNode node in parentNode.Nodes)
            {
                var privilegio = (BEPrivilegio.PrivilegioRow)node.Tag;

                if (roleRights.FindBylit_privilegio_id(privilegio.lit_privilegio_id) != null)
                    rightsTree.CheckNodeByTag(node.Tag, SIL.FieldWorks.Common.Controls.TriStateTreeView.CheckState.Checked);
                else rightsTree.CheckNodeByTag(node.Tag, SIL.FieldWorks.Common.Controls.TriStateTreeView.CheckState.Unchecked);

                CheckTreeNodes(node, roleRights);
                
            }
        }
        private void CheckRightsInList(BEPrivilegio.PrivilegioDataTable roleRights)
        {
            for (int i = 0; i < rightsList.Items.Count; i++)
            {
                BEPrivilegio.PrivilegioRow privilegio = (BEPrivilegio.PrivilegioRow)((System.Data.DataRowView)rightsList.Items[i]).Row;
                

                bool authorized = (roleRights.FindBylit_privilegio_id(privilegio.lit_privilegio_id) != null);
                rightsList.SetItemChecked(i, authorized);
            }
            
        }
        public void ClearControls(ControlCollection controls)
        {
            base.ClearControls(controls);
            selectedRole = null;
        }
        private bool ValidateEntries()
        {
            bool functionReturnValue = false;
            string msg = "";
            
            if (string.IsNullOrEmpty(txtNombre.Text))
            {
                msg = "Debe ingresar el nombre del rol";
                txtNombre.Focus();
            }
            else if (string.IsNullOrEmpty(txtDesc.Text))
            {
                msg = "Debe ingresar la descripción del rol";
                txtDesc.Focus();
            }
            else
                functionReturnValue = true;

            if (!functionReturnValue)
                MessageBox.Show(msg, Text, MessageBoxButtons.OK, MessageBoxIcon.Exclamation);

            return functionReturnValue;
        }
        private void Save()
        {
            
            try
            {
                Cursor.Current = Cursors.WaitCursor;
                if (ValidateEntries())
                {
                    if (selectedRole == null)
                        CreateRole();
                    else
                        UpdateRole();

                    ClearControls(Controls);
                    LoadRolesGrid(false);
                }
            }
            catch (Exception ex)
            {
                DisplayError("No se pudo guardar la información.", ex);
            }
            finally
            {
                Cursor.Current = Cursors.Default;
            }
        }
        private void PackRights(TreeNode parentNode, ArrayList rightArray)
        {
            foreach (TreeNode node in parentNode.Nodes)
            {
                if (rightsTree.GetChecked(node) != SIL.FieldWorks.Common.Controls.TriStateTreeView.CheckState.Unchecked)
                {
                    rightArray.Add(((BEPrivilegio.PrivilegioRow)node.Tag).lit_privilegio_id);
                    PackRights(node, rightArray);
                }
            }

            for (int i = 0; i < rightsList.CheckedItems.Count; i++)
                rightArray.Add(((BEPrivilegio.PrivilegioRow)((System.Data.DataRowView)rightsList.CheckedItems[i]).Row).lit_privilegio_id);
        }
        private int CreateRole()
        {
            ArrayList rights = new ArrayList();
            BCSecurity securityObject = new BCSecurity();
            PackRights(rightsTree.TopNode, rights); 
            int newRoleId = securityObject.CreateRole(txtNombre.Text, txtDesc.Text, NortecMembership.ApplicationId, rights);
            if (newRoleId > 0) 
                ShowConfirmation("El rol fue creado con éxito");
            else if (newRoleId == 0)
                ShowError("El rol que usted está intentando agregar ya existe");
            else ShowError("No se pudo agregar el rol debido a un error inesperado");
            return newRoleId;
        }
        private int UpdateRole()
        {
            ArrayList rights = new ArrayList();
            BCSecurity securityObject = new BCSecurity();
            PackRights(rightsTree.TopNode, rights);
            bool success = securityObject.UpdateRole(txtNombre.Text, txtDesc.Text, selectedRole.lit_rol_id, rights);
            if (success)
                ShowConfirmation("El rol fue actualizado con éxito");
            else ShowError("Se encontró un error durante la actualización del rol");

            return selectedRole.lit_rol_id;
        }
        private void Delete() {
            try
            {
                Cursor.Current = Cursors.WaitCursor;
                if (selectedRole == null)
                    MessageBox.Show("Debe seleccionar un registro antes de eliminarlo.", Text, MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                else
                {
                    if (MessageBox.Show("¿Está seguro de eliminar el rol \"" + selectedRole.lit_rol_nombre + "\"?", Text, MessageBoxButtons.YesNo, MessageBoxIcon.Question, MessageBoxDefaultButton.Button2) == DialogResult.Yes)
                    {
                        BCSecurity securityObject = new BCSecurity();
                        bool success = securityObject.DeleteRole(selectedRole.lit_rol_nombre, NortecMembership.ApplicationId, true);
                        if (!success)
                            ShowError("El rol no pudo ser borrado debido a que tiene usuarios asociados");
                        else
                        {
                            LoadRolesGrid(false);
                            ShowConfirmation("El rol fue eliminado con éxito");
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                DisplayError("No se pudo eliminar el rol debido a un error inesperado.", ex);
            }
            finally
            {
                Cursor.Current = Cursors.Default;
            }
        }
        #endregion
    }
}